<?php
/**
 * 
 * @author bqd
 *
 */
class MultiLocaleBehavior extends ModelBehavior {
	var $options = array();
	var $locale = null;
	var $__defaultName = "Translate";
	var $__is_default_language = false;
	var $languages = array();
    function setup(&$model, $settings = array()) {
        if (!count($this->languages)) {
        	$this->languages = Configure::read('Config.languages'); 
        }
    	
    	$default = array(
        	'fields'		=>	array(),
			'translate_table'	=>	'',
		);

		if (!isset($this->__settings[$model->alias])) {
			$this->__settings[$model->alias] = $default;
		}
		
		$this->modelName = $model->alias;
		$this->__settings[$model->alias] = am($this->__settings[$model->alias], $settings);
		
//		debug($this->locale);
		$this->translateName[$model->alias] = $this->getTranslationModelName($model);
		
		$this->table[$model->alias] = $model->table;
		
		
    	if (!empty($this->__settings[$model->alias]['translate_table'])) {
    		$this->translateTable[$model->alias] = $this->__settings[$model->alias]['translate_table'];
    	} else {
    		$this->translateTable[$model->alias] = $this->table[$model->alias]."_translates";
    		
    	}
    }
    
    function beforeFind(&$model, $query) {
   		$this->locale = $this->__getLocale();

    	// If language is default, do nothing
    	if ($this->__is_default_language) {
    		return $query;
    	}
    	$this->findQueryType[$model->alias] = $model->findQueryType;
    	if ($this->findQueryType[$model->alias] == "count") {
    		return $query;
    	}
    	
    	$settings = $this->__settings[$model->alias];
    	
    	if (!isset($query['joins'])) {
    		$query['joins'] = array();
    	}
    	
    	// merge fields
    	if (!is_array($query['fields']) || empty($query['fields'])) {
    		$query['fields'] = array("{$model->alias}.*", "{$this->translateName[$model->alias]}.*");
    	} else {
	    	foreach ($settings['fields'] as $field) {
//	    		$query['fields'][] = "{$this->translateName[$model->alias]}.*";
	    		if (in_array($field, $query['fields']) || in_array("{$model->alias}.{$field}", $query['fields'])) {
	    			$query['fields'][] = "{$this->translateName[$model->alias]}.{$field}";
	    		}
	    	}
    	}
    	    	
    	$query['fields'][] = "{$this->translateName[$model->alias]}.id";
    	
    	//$query['fields'] = array_merge($query['fields'], $settings['fields']);
    	$query['joins'][] = array(
			'table' => $this->translateTable[$model->alias],
			'type' => 'LEFT',
			'alias' => $this->translateName[$model->alias],
			'conditions' => array(
				"{$this->translateName[$model->alias]}.locale"	=>	$this->locale,
				"{$this->translateName[$model->alias]}.foreign_key = {$model->alias}.id"
			),
		);
		
		
//		debug($query);
		return $query;
    	
    }
    
    function afterFind(&$model, $results, $primary) {
    	$this->locale = $this->__getLocale();
	    // If language is default, do nothing
    	if ($this->__is_default_language) {
    		return $results;
    	}
    	
    	if ($this->findQueryType == "count") {
    		return $results;
    	}
    	
    	/**
    	 * Các trường hợp có thể xuất hiện:
    	 * a. Tìm thấy dữ liệu ngôn ngữ tương ứng
    	 * b. Không tìm thấy dữ liệu ngôn ngữ tương ứng
    	 */
    	
    	for ($i = 0; $i < count($results); $i++) {
    		/**
	    	 * a. Nếu tìm thấy dữ liệu ngôn ngữ tương ứng, nạp dữ liệu vào
	    	 */
	    	if (!empty($results[$i][$this->translateName[$model->alias]]['id'])) {
	    		foreach ($results[$i][$this->translateName[$model->alias]] as $field => $value) {
	    			if ($field != 'id') {
	    				$results[$i][$model->alias][$field] = $value;
	    			}
	    		}
	    	}
    	}
    	return $results;
    	//exit;
    }
    
    function beforeSave(&$model) {
    	$this->locale = $this->__getLocale();
//    	debug($this->locale);exit;
    	
    	$created = !isset($model->data[$model->alias]['id']);
    	
    	// Trường hợp là ngôn ngữ mặc định, không làm gì cả.
    	if ($this->__is_default_language) {
    		return true;
    	}
    	
    	// Trường hợp là ngôn ngữ phụ
    	// Nếu phương thức lưu là tạo mới, xử lý lưu vào bảng phụ sau khi đã lưu vào bảng chính
    	// @see: afterSave()
    	
    	// Nếu phương thức là cập nhật, không lưu vào bảng chính, chỉ lưu vào bảng phụ (xóa các trường translate ra)
    	if (!$created) {
    		/**
    		 * Nạp dữ liệu cho bảng phụ
    		 */ 
    		// Bind model
//			$model->bindModel(array(
//				'hasMany' => array(
//					$this->translateName[$model->alias] => array(
//						'className' => $this->translateName[$model->alias], 
//						'foreignKey' => 'foreign_key',
//						'dependent'=> true,
//						'conditions' => '',
//					)
//				)
//			), false);
			$this->bindTranslateModel($model);
			
			// Tạo dữ liệu cho bảng phụ
			// Nếu dữ liệu có rồi thì save lại
			$updateData = array();
			$data = array();
			foreach ($this->__settings[$model->alias]['fields'] as $field) {
				$updateData[$field] = "'{$model->data[$model->alias][$field]}'";
				$data[$this->translateName[$model->alias]][$field] = $model->data[$model->alias][$field];
				
				// Xóa các trường ngôn ngữ của bảng chính để không bị ảnh hưởng
				unset($model->data[$model->alias][$field]);
			}
			
			$model->{$this->translateName[$model->alias]}->updateAll(
				$updateData, //fields
				array(
					"{$this->translateName[$model->alias]}.foreign_key" => $model->data[$model->alias]['id'],
					// identify language to translate
					"{$this->translateName[$model->alias]}.locale" => $this->locale,
				)
			);
			
			/**
			 * Nếu không có bảng ghi hiệu ứng, chứng tỏ chưa có record cho ngôn ngữ này
			 * => Tiến hành tạo mới
			 */
			if (!$model->{$this->translateName[$model->alias]}->getAffectedRows()) {
				$data[$this->translateName[$model->alias]]['locale'] = $this->locale;
				$data[$this->translateName[$model->alias]]['foreign_key'] = $model->data[$model->alias]['id'];
				
				$model->{$this->translateName[$model->alias]}->create($data);
				$model->{$this->translateName[$model->alias]}->save($data);
			}
    	}
    	
    	//debug($model->data);
    }
    
    // FIXME: Đang làm nửa chừng
    function afterSave(&$model, $created) {
    	// Trường hợp là ngôn ngữ mặc định, không làm gì cả.
    	if ($this->__is_default_language) {
    		return true;
    	}
    	
    	// Nếu phương thức lưu là tạo mới, xử lý lưu vào bảng phụ sau khi đã lưu vào bảng chính
    	if ($created) {
    		// Tạo dữ liệu cho bảng phụ
			// Nếu dữ liệu có rồi thì save lại
			$data = array();
			foreach ($this->__settings[$model->alias]['fields'] as $field) {
				$data[$this->translateName[$model->alias]][$field] = $model->data[$model->alias][$field];
			}
			
			
			$data[$this->translateName[$model->alias]]['locale'] = $this->locale;
			$data[$this->translateName[$model->alias]]['foreign_key'] = $model->id;
			
			$this->bindTranslateModel($model);
			
			$model->{$this->translateName[$model->alias]}->create($data);
			$model->{$this->translateName[$model->alias]}->save($data);
    	}
    	return true;
    }
    
    function bindTranslateModel(&$model) {
    	$model->bindModel(array(
			'hasMany' => array(
				$this->translateName[$model->alias] => array(
					'className' => $this->translateName[$model->alias], 
					'foreignKey' => 'foreign_key',
					'dependent'=> true,
					'conditions' => array(
						"{$this->translateName[$model->alias]}.locale" => $this->locale
					),
				)
			)
		), false);
    }
//	function bindTranslation(&$model, $fields, $reset = true, $multiple = false) {
//		$settings = $this->__settings[$model->alias];
//		
//		if (is_string($fields)) {
//			$fields = array($fields);
//		}
//		
//		$className = $this->getTranslationModelName($model);
//		
//		$default = array(
//			'className' => $className, 
//			'foreignKey' => 'foreign_key',
//			'dependent'=> true,
//			'conditions' => '',
//		);
//		
//		$associations = array();
//		// default table language
//		$fields = array_merge($this->settings[$model->alias], $fields);
//		
//		if($multiple) {
//			$model->unbindModel(array(
//				'hasOne' => array($className)
//			), $reset);
//			// init association
//			$associations[$className] = array_merge($default, array(
//				"fields" => $fields,
//				"conditions" => array($className.".locale" => array("eng","vie"))
//			));
//			//debug($model->useTranslation);exit();
//			$model->bindModel(array('hasMany' => $associations), $reset);
//		}
//		else {
//
//			$model->unbindModel(array(
//				'hasMany' => array($className)
//			), $reset);
//			
//			$locale = $this->locale;
//			// init association
//			$associations[$className] = array_merge($default, array(
//				"fields" => $fields,
//				"conditions" => array($className.".locale" => $locale)
//			));
//
//			$model->bindModel(array('hasOne' =>	$associations), $reset);
//		}
//		return $model;
//	} 
	
	function getTranslationModelName(&$model) {
		$settings = $this->__settings[$model->alias];
		if (!isset($settings['translate_table']) || empty($settings['translate_table'])) {
			$className = Inflector::pluralize($model->alias). $this->__defaultName;
		} else {
			$className = Inflector::classify($settings['translate_table']);
		}
		return $className;
	}
	
	function __getLocale() {
		if (!isset($this->locale)) {
			$default_locale = Configure::read('Config.default_language');
	
			if (isset($_SESSION['Config']['language'])) {
	    		$locale = $_SESSION['Config']['language'];
	    	} else {
	    		$locale = $default_locale;
	    	}
	    	
	    	$this->__is_default_language = ($locale == $default_locale);
	    	
	    	return $locale;
		} else {
			return $this->locale;
		}
	}
//	function afterFind(&$model, $results, $primary) {
//		$className = $this->getTranslationModelName($model);
//		
//		//$fields = $this->settings[$model->alias];
//		
//		foreach ($results as $key => $data) {
//			if(isset($data[$className])) {
//				$translateData = $data[$className];
//				
//				foreach ($translateData as $field => $value) {
//					if(!in_array($field,array("id", "foreign_key"))) {
//						if(is_array($value)) {
//							if(isset($value['id'])) {
//								unset($value['id']);
//							}
//							$results[$key][$model->alias] = array_merge($results[$key][$model->alias],$value);
//							
//						}else{
//							$results[$key][$model->alias][$field] =  $value;
//						}
//					}
//				}
//			}
//		}
//		return $results;
//	}
}
?>